use tokio::io::AsyncReadExt;

use crate::{error::{new_err, AppErr}, service::frame::{HEAD, MIN_LEN}, utils::{codec::decode_u16, new_buf}};

use super::frame::RecvFrame;

pub async fn read_frame<R: AsyncReadExt + Unpin>(r: &mut R) -> Result<RecvFrame, AppErr> {
    let mut buf = [0u8; 4];
    r.read_exact(&mut buf).await?;

    let head = decode_u16(&buf);
    if head != HEAD {
        return Err(new_err("invalid head"));
    }

    let len = decode_u16(&buf[2..]) as usize;
    if len < MIN_LEN {
        return Err(new_err("invalid len"));
    }

    let mut buf = new_buf(len - 4);
    r.read_exact(&mut buf).await?;

    Ok( RecvFrame::new(buf) )
}











